package sim;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Stack;

import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

import prepro.SerializeStopWordObject;
import prepro.SerializeTermsToInt;

import tWeight.TfIdf;

import matrics.SparseVector;
import myLucene.Props;
import myLucene.TfIdfOld;

public class Sim {

	/**
	 * @param args
	 * @throws Exception
	 */
	public static HashMap<Integer, Double> startSimTF(SparseVector target,
			String[] intToTerms, IndexReader iReader) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("Sim.startSimTF");
		String pathname = "/local/joofeit/TFIDF_" + Props.windowSize;

		HashMap<Integer, Double> similarities = new HashMap<Integer, Double>();
		int counter = 0;
		File file = new File(pathname);
		if (file.isDirectory()) {
			File[] fList = file.listFiles();
			for (File curFile : fList) {

				int curInt = Integer.parseInt(curFile.getAbsolutePath().split(
						"/")[4].split("_")[1]);
				String curTerm = curFile.getAbsolutePath().split("/")[4]
						.split("_")[2];
				// System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>> "
				// + curFile.getAbsolutePath().split("/")[4]);
				if (!curTerm.equals(intToTerms[curInt])) {
					throw new Exception(
							"Severe Error: !curTerm.equals(intToTerms[curInt])");
				}
				System.out.println(curTerm);
				System.out.println(counter + " " + curFile.getAbsolutePath());

				// int[] array =
				// ReadObject.readArray(curFile.getAbsolutePath());
				// Stack<Integer> stops =
				// SerializeStopWordObject.deserializeStops();
				SparseVector sp = deserializeTFIDF(curFile.getAbsolutePath());
				// SparseVector sp = TfIdf.getTfIdf(array, iReader, stops);
				double sim = Cosin.getCosin(target, sp);
				similarities.put(curInt, sim);
				System.out.println(curTerm + " " + sim);
				// writeToFileArray(array, intToTerms);
				counter++;
			}
		}
		return similarities;
	}

	public static HashMap<Integer, Double> startSimDist(File target,
			LinkedList<Integer>[] idiom, Stack<Integer> stops,
			String[] intToTerms) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("startSimDist");
		String dataType = "dist";
		String pathname = "/local/joofeit/DISTFILTERED6/results_6_"
				+ target.getName().replace("_dist_6_.data", "");
		HashMap<Integer, Double> similarities = new HashMap<Integer, Double>();
		Directory iDirectory = FSDirectory.open(new File(Props.readIndexPath));
		IndexSearcher searcher = new IndexSearcher(iDirectory, true);
		SparseVector[] idiomDistArray = MakeDistObjects.makeDistVector(idiom);
		IndexReader iReader = searcher.getIndexReader();
		File file = new File(pathname);
		System.out.println("-----------------" + pathname);
		if (file.isDirectory()) {
			File[] fList = file.listFiles();
			System.out.println("HIER!!!!!!!!!!!!");
			Collections.sort(Arrays.asList(fList));
			// Stack<Integer> stops =
			// SerializeStopWordObject.deserializeStops();
			// String[] intToTerms = TfIdfOld.getIntToTerms();
			for (File curFile : fList) {
				System.out.println("-------" + curFile.getName());
				int curInt = Integer.parseInt(curFile.getAbsolutePath().split(
						"/")[5].split("_")[0]);
				String curTerm = curFile.getAbsolutePath().split("/")[5]
						.split("_")[1];
				if (!curTerm.equals(intToTerms[curInt])) {
					throw new Exception(
							"Severe Error: !curTerm.equals(intToTerms[curInt])");
				}
				// if (!stops.isEmpty()) {
				// if (curInt == stops.peek()) {
				// stops.pop();
				// continue;
				// }
				// }
				System.out.println(curTerm);
				System.out.println(curFile.getAbsolutePath());

				LinkedList<Integer>[] array = ReadObject
						.readLinkedListArray(curFile.getAbsolutePath());
				// writeToFileLinkedList(array, intToTerms);
				SparseVector[] targetVerbArray = MakeDistObjects
						.makeDistVector(array);
				System.out.println("Start calcSim");
				double sim = calcSim(targetVerbArray, idiomDistArray,
						intToTerms);
				similarities.put(curInt, sim);
				System.out
						.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ "
								+ curTerm + " " + sim);
			}
		}
		return similarities;
	}

	public static double calcSim(SparseVector[] targetVerbArray,
			SparseVector[] idiomDistArray, String[] intToTerms)
			throws Exception {
		double accumulatedSimilarity = 0.0;
		Stack<Integer> stops = SerializeStopWordObject.deserializeStops();
		int counter = 0;
		double[] similarities = new double[targetVerbArray.length];
		if (targetVerbArray.length != idiomDistArray.length) {
			throw new Exception(
					"Computing Distance similarity: targetVerbArray.length != idiomDistArray.length");

		} else {
			for (int i = 0; i < targetVerbArray.length; i++) {
				if (!stops.isEmpty()) {
					if (i == stops.peek()) {
						stops.pop();
						continue;
					}
				}
				if (targetVerbArray[i].isEmpty || idiomDistArray[i].isEmpty) {
					similarities[i] = 0.0;
					continue;
				}
				double sim = Cosin.getCosin(idiomDistArray[i],
						targetVerbArray[i]);
				similarities[i] = sim;

				accumulatedSimilarity += sim;
				// if(idiomDistArray[i].norm()> 0 ||
				// targetVerbArray[i].norm()!=0){
				if (sim > 0.0) {
					counter++;

				}
			}
		}
		double normalizedSim = 0.0;
		if (counter == 0) {

		} else {
			normalizedSim = accumulatedSimilarity / (double) (counter);
		}
		System.out.println("normalizedSim " + " " + normalizedSim + " counter "
				+ counter);

		return normalizedSim;
	}

	private static void writeToFileLinkedList(LinkedList<Integer>[] array,
			String[] intToTerms) {

		for (int x = 0; x < array.length; x++) {
			StringBuffer str = new StringBuffer();

			str.append(intToTerms[x] + " ");
			LinkedList<Integer> ll = array[x];
			for (int i : ll) {
				str.append(i + " ");
			}
			if (!ll.isEmpty()) {
				System.out.println(str.toString());
			}

		}

	}

	private static void writeToFileArray(int[] array, String[] intToTerms) {
		for (int x = 0; x < array.length; x++) {
			System.out.println(intToTerms[x] + " " + array[x]);

		}
	}

	private static double[] distSim(LinkedList<Integer>[] dist,
			LinkedList<Integer>[] targetArray, Stack<Integer> stops)
			throws Exception {

		double[] sims = new double[Props.distanceSectionsLength];
		for (int x = 0; x < dist.length; x++) {
			if (stops.peek() == x) {
				continue;
			}
			LinkedList<Integer> target = targetArray[x];
			LinkedList<Integer> verb = dist[x];
			SparseVector svVerb = DistVector.distToSparseVectors(verb);
			SparseVector svTarget = DistVector.distToSparseVectors(target);
		}
		return sims;

	}

	private static SparseVector deserializeTFIDF(String path)
			throws FileNotFoundException, IOException, ClassNotFoundException {
		File file2 = new File(path);
		ObjectInputStream in = new ObjectInputStream(new FileInputStream(file2));
		// Deserialize the object
		SparseVector sp_in = (SparseVector) in.readObject();
		in.close();
		return sp_in;

	}

}
